/******************************************************************************
*    Copyright (C), 2022 by D2X studio. All rights reserved.                  *
*                                                                             *
*    @file:      socket_server.c
*    @owner:     zhengjian.xie@gmail.com                                      *
*    @desc:                                                                   *
*    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +    *
* history:                                                                    *
*  <author>      <time>      <version>              <description>             *
*  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  *
*  |  Xzj |  20220423[13:51] | 1.0.0 |                  build              |  *
*  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  *
******************************************************************************/
#include "includes.h"
#include "sys/types.h"
#include "sys/socket.h"
#include <arpa/inet.h>
#include <errno.h>

#define MAX_CLIENT_CNT 10

/** socket server data define */
static stEvent __sock_server_evt__ = { -1, no, nil };
static stEvent sock_clients[MAX_CLIENT_CNT];

void sock_server_callback(void* pVoid) {
    int fd, ret;
    char buf[128] = { 0 };

    if ( pVoid == &(__sock_server_evt__) ) {
        fd = accept(__sock_server_evt__.fd, NULL, NULL);
        if ( fd <= 0 ) {
            printf("socket server accept error: %d\n", errno);
            return ;
        }
        for ( i = 0; i < MAX_CLIENT_CNT; i++ ) {
            if ( sock_clients[i].fd < 0 ) {
                sock_clients[i].fd = fd;
                app_event_add(&sock_clients[i]);
            }
        }
        return ;
    }
!|!4<Mouse>C!}!4
    pstEvent pEvt = (pstEvent) pVoid;
    ret = read(pEvt->fd, buf, 128);
    if ( ret <= 0 ) {
        printf("socket server read error: %d\n", errno);
        return ;
    }

    // handle buf

    //for ( i = 0; i < MAX_CLIENT_CNT; i++ ) {
    //}
}

/** sock_server_init */
void sock_server_init(void) {
    uint8_t i;
    struct sockaddr_in svr_addr = { 0 };
    struct sockaddr_in cli_addr = { 0 };

    __sock_server_evt__.doEvent = sock_server_callback;
    for ( i = 0; i < MAX_CLIENT_CNT; i++ ) {
        sock_clients[i].fd = -1;
        sock_clients[i].is_eventfd = no;
        sock_clients[i].doEvent = sock_server_callback;
    }

    // (1) create socket
    __sock_server_evt__.fd = socket(AF_INET, SOCK_STREAM, 0);

    // (2) bind address
    svr_addr.sin_family = AF_INET;
    svr_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    svr_addr.sin_port = htons(8080);
    bind(__sock_server_evt__.fd, (struct sockaddr*)&svr_addr, sizeof(svr_addr));

    // (3) listen
    listen(__sock_server_evt__.fd, 50);

    // (4) async accept
    app_event_add(&__sock_server_evt__);
}

/** sock_server_deinit */
void sock_server_deinit(void) {
    app_event_del(&__sock_server_evt__);
}

void sock_server_sendstr(int idx, const char* str) {
    if ( __sock_server_evt__.fd > 0 ) {
        write(__sock_server_evt__.fd, str, strlen(str) + 1);
    }
}
